#ifndef BTL_DEMO_FEATUREDEMO_QFEATUREDEMOAPPLICATION
#define BTL_DEMO_FEATUREDEMO_QFEATUREDEMOAPPLICATION

#include <QApplication>
#include <QTimer>
#include <btl/extra/VideoSource/VideoSourceUEye.hpp>
#include <btl/extra/Gui/QImageView.hpp>
#include <btl/Utility/OpenCVSupport.hpp>
#include <btl/extra/Gui/ImagePainter.hpp>
#include <btl/Features/FeatureDescriptor.hpp>
#include <boost/program_options.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iostream>
#include <iterator>

class QFeatureDemoApplication : public QApplication
{

      Q_OBJECT

   public:

      QFeatureDemoApplication(int& argc, char** argv) : QApplication(argc, argv), _detector(10, true)
      {
         _pTimer = new QTimer;
         _pView = new btl::extra::QImageViewRGB;
         _pView->show();
         connect(_pTimer, SIGNAL(timeout()), this, SLOT(update()));
         _pTimer->start(30);
      }

      ~QFeatureDemoApplication() {}

   protected Q_SLOTS:

      void update()
      {
         _descriptors.clear();
         btl::ImageRegionConstRGB frame = _videoSource.getNextFrame();
         std::vector<cv::KeyPoint> cvKeyPoints;
         _detector.detect(btl::cvUnsafeUnconstImage(frame), cvKeyPoints);
         btl::ImageRGB output(frame);
         _painter.setImage(output);
         std::vector<cv::KeyPoint>::iterator it;
         const int halfPatchSize = patchSize / 2;
         Eigen::AlignedBox<int, 2> safeRegion(
            Eigen::Vector2i(halfPatchSize, halfPatchSize),
            Eigen::Vector2i(frame.width() - halfPatchSize - 1, frame.height() - halfPatchSize - 1));
         for(it = cvKeyPoints.begin(); it != cvKeyPoints.end(); ++it)
         {
            cv::KeyPoint cvKeyPoint = *it;
            int x = cvKeyPoint.pt.x;
            int y = cvKeyPoint.pt.y;
            if(safeRegion.contains(Eigen::Vector2i(x, y)))
            {
               _descriptors.push_back(btl::PatchFeatureDescriptor<btl::PixelRGB, patchSize, patchSize>(frame, x, y));
               _painter.drawCircle(x, y, 3, btl::PixelRGB(0, 0, 255));
            }
         }
         _pView->setImage(output);
      }

   protected:

      QTimer* _pTimer;

      btl::extra::VideoSourceUEye _videoSource;

      btl::extra::QImageViewRGB* _pView;

      cv::FastFeatureDetector _detector;

      btl::extra::ImagePainter<btl::PixelRGB> _painter;

      static const int patchSize = 9;

      std::vector< btl::PatchFeatureDescriptor<btl::PixelRGB, patchSize, patchSize> > _descriptors;

};

#endif //BTL_DEMO_FEATUREDEMO_QFEATUREDEMOAPPLICATION
